package cn.wolfcode.wolf2w.service.impl;

import cn.wolfcode.wolf2w.domain.Destination;
import cn.wolfcode.wolf2w.domain.StrategyCatalog;
import cn.wolfcode.wolf2w.query.StrategyCatalogQuery;
import cn.wolfcode.wolf2w.repository.StrategyCatalogRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IStrategyCatalogService;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.util.DBHelper;
import cn.wolfcode.wolf2w.vo.CatalogVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* 攻略分类服务接口实现
*/
@Service
//@Transactional  现在写不能事务, 需要讲完复制集才能使用事务
public class StrategyCatalogServiceImpl implements IStrategyCatalogService {

    @Autowired
    private StrategyCatalogRepository repository;
    @Autowired
    private IDestinationService destinationService;
    @Autowired
    private MongoTemplate template;

    @Autowired
    private IStrategyService strategyService;



    @Override
    public void save(StrategyCatalog strategyCatalog) {
        strategyCatalog.setId(null);
        repository.save(strategyCatalog);
    }

    @Override
    public void update(StrategyCatalog strategyCatalog) {
        repository.save(strategyCatalog);
    }

    @Override
    public void delete(String id) {
        repository.deleteById(id);
    }

    @Override
    public StrategyCatalog get(String id) {
        return repository.findById(id).orElse(null);
    }

    @Override
    public List<StrategyCatalog> list() {
        return repository.findAll();
    }

    @Override
    public Page<StrategyCatalog> query(StrategyCatalogQuery qo) {
        Query query = new Query();
        Pageable pageable = PageRequest.of(qo.getCurrentPage()- 1,qo.getPageSize(), Sort.Direction.ASC, "_id");
        return DBHelper.query(template,pageable, query,StrategyCatalog.class);
    }

    @Override
    public void saveOrUpdate(StrategyCatalog strategyCatalog) {
        // 保存或修改之前需要根据关联的目的地id查询到对应的name，再把它保存到攻略明细的类中保存
        Destination destination = destinationService.get(strategyCatalog.getDestId());
        strategyCatalog.setDestName(destination.getName());
        if(StringUtils.hasLength(strategyCatalog.getId())){
            //update
            this.update(strategyCatalog);
        }else{
            //save
            this.save(strategyCatalog);
        }
    }

    @Override
    public List<CatalogVO> GroupList() {
        List<CatalogVO> list = new ArrayList<>();
        /* 进行聚合查询  在mongodb的写法
        db.strategy_catalog.aggregate([{
            $group:{_id: "$destName",names:{$push: "$name"},ids:{$push:"$id"}}
        }])*/
        TypedAggregation<StrategyCatalog> agg = Aggregation.newAggregation(StrategyCatalog.class,
                Aggregation.group("destName").push("name").as("names").push("id").as("ids"));
        // 执行上面的语句后结果用Map集合接收结果集
        AggregationResults<Map> results = template.aggregate(agg, Map.class);
        //将结果转化成list<map> map描述一行数据
        List<Map> data = results.getMappedResults();
        for (Map map : data) {
            // 遍历list中的数据，封装成一个个的CatalogVO对象
            CatalogVO vo = new CatalogVO();
            // 获取到目的地的名称封装的vo的destName字段上
            vo.setDestName(map.get("_id").toString());
            // 获取所有的name数据集合
            List<Object> names = (List<Object>) map.get("names");
            // 获取所有的id数据集合
            List<Object> ids = (List<Object>) map.get("ids");
            // 封装StrategyCatalog数据
            List<StrategyCatalog> catalogs = new ArrayList<>();
            if (names != null && names.size() > 0) {
                for (int i = 0; i < names.size(); i++) {
                    // 封装分类的名称和id
                    StrategyCatalog catalog = new StrategyCatalog();
                    catalog.setName(names.get(i).toString());
                    catalog.setId(ids.get(i).toString());
                    // 把分类名称和id封装到catalog对象中
                    catalogs.add(catalog);
                }
                // 把封装分类名称和id的catalogs集合设置到vo对象中
                vo.setCatalogList(catalogs);
            }
            // 把vo对象添加到list集合中
            list.add(vo);
        }
        return list;
    }

    @Override
    public List<StrategyCatalog> findCatalogAndSubInfo(String destId) {
        List<StrategyCatalog> catalogs = repository.findByDestId(destId);
        for (StrategyCatalog catalog : catalogs) {
            catalog.setStrategies(strategyService.queryByCatalogId(catalog.getId()));
        }
        return catalogs;
    }
}
